//*******************************************************************
//	created:	11:5:2011   11:50
//	filename: 	stdiofile.cpp
//	author:		tiamo
//	purpose:	stdio file
//*******************************************************************

#include "stdafx.h"
#include "stdiofile.h"

namespace utils
{
	//
	// constructor
	//
	StdioFile::StdioFile()
	{
		mFile																= nullptr;
	}

	//
	// destructor
	//
	StdioFile::~StdioFile()
	{
		close();
	}

	//
	// open file
	//
	bool StdioFile::openFile(wchar_t const* fileName, wchar_t const* openMode)
	{
		close();
	#ifdef WIN32
		_wfopen_s(&mFile, fileName, openMode);
	#else
		mFile																= fopen(wideToUtf8(fileName).c_str(), wideToUtf8(openMode).c_str());
	#endif
		return !!mFile;
	}

	//
	// close
	//
	void StdioFile::close()
	{
		if(!mFile)
			return;

		fclose(mFile);
		mFile																= nullptr;
	}

	//
	// get content
	//
	DataBuffer StdioFile::getContent()
	{
		uint64_t offset														= getOffset();
		uint64_t fileSize													= getFileSize();
		DataBuffer retBuffer(static_cast<uint32_t>(fileSize));
		seek(0, SEEK_SET);
		retBuffer.resize(readBuffer(retBuffer.getBuffer(), retBuffer.getSize()));
		seek(offset, SEEK_SET);
		return retBuffer;
	}

	//
	// seek
	//
	uint64_t StdioFile::seek(uint64_t offset, int seekMode)
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);

	#ifdef WIN32
		return static_cast<uint64_t>(_fseeki64(mFile, static_cast<__int64>(offset), seekMode));
	#else
		return static_cast<uint64_t>(fseeko64(mFile, static_cast<off64_t>(offset), seekMode));
	#endif
	}

	//
	// read buffer
	//
	uint32_t StdioFile::readBuffer(void* dataBuffer, uint32_t bufferLength)
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);

	#ifdef WIN32
		return static_cast<uint32_t>(fread_s(dataBuffer, bufferLength, sizeof(uint8_t), bufferLength, mFile));
	#else
		return static_cast<uint32_t>(fread(dataBuffer, sizeof(uint8_t), bufferLength, mFile));
	#endif
	}

	//
	// write buffer
	//
	uint32_t StdioFile::writeBuffer(void const* dataBuffer, uint32_t bufferLength)
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);

		return static_cast<uint32_t>(fwrite(dataBuffer, sizeof(uint8_t), bufferLength, mFile));
	}

	//
	// set file size
	//
	void StdioFile::setFileSize(uint64_t fileSize)
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);
	}

	//
	// get offset
	//
	uint64_t StdioFile::getOffset()
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);

	#ifdef WIN32
		return static_cast<uint64_t>(_ftelli64(mFile));
	#else
		return static_cast<uint64_t>(ftello64(mFile));
	#endif
	}

	//
	// get length
	//
	uint64_t StdioFile::getFileSize()
	{
		if(!mFile)
			ThrowException(L"StdioFile(%p): invalid file", this);

		uint64_t offset														= getOffset();
		seek(0, SEEK_END);
		uint64_t fileSize													= getOffset();
		seek(offset, SEEK_SET);
		return fileSize;
	}
}
